/*
 * @Author: wangxing wangxing@kd.com
 * @Date: 2025-01-07 14:47:59
 * @LastEditors: wangxing wangxing@kd.com
 * @LastEditTime: 2025-05-16 11:19:43
 * @FilePath: \quick-front\static\drawio\js\grapheditor\SidebarScan.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/**
 * 根据页面和图中添加的图形.创建一个所有图形之间的树形关系的侧边浏览窗口
 */
function SidebarScan(editorUi, container) {
  this.editorUi = editorUi;
  this.sidebar = editorUi.sidebar;
  this.container = container;
  this.graph = editorUi.createTemporaryGraph(this.editorUi.editor.graph.getStylesheet());
  this.graph.cellRenderer.minSvgStrokeWidth = 1;
  this.graph.cellRenderer.antiAlias = false;
  this.graph.container.style.visibility = 'hidden';
  this.graph.foldingEnabled = false;

  this.treeData = []; // zTree数据

  this.visible = true;

  // 搜索输入框元素
  this.searchInput = null;
  this.hide();
  this.installListener();
  this.createSearchInput();

  const div = document.createElement('div');
  div.id = 'scanTree';
  div.className = 'ztree';
  div.style.width = '100%';
  div.style.height = '100%';

  this.container.appendChild(div);
  this.createScanTree(); //创建树结构
}

SidebarScan.prototype.installListener = function() {
  const graph = this.editorUi.editor.graph;
  // graph.addListener(mxEvent.CELLS_ADDED, mxUtils.bind(this, this.processCellAdd))
  drawioBus.$on(
    'removeTreeNode',
    mxUtils.bind(this, function(treeNode) {
      const ids = (function loop(tree, temp) {
        if (!tree) return temp;
        if (Array.isArray(tree)) {
          tree.forEach(item => loop(item, temp));
        } else if (tree.children) {
          tree.children.forEach(item => loop(item, temp));
        }
        tree.relateId && temp.push(tree.relateId);
        return temp;
      })(treeNode, []);
      this.removeNodesByIds(ids);
    })
  );
};

SidebarScan.prototype.show = function() {
  if (!this.visible) {
    this.container.style.display = 'block';
    this.visible = true;
  }
};

SidebarScan.prototype.hide = function() {
  if (this.visible) {
    this.container.style.display = 'none';
    this.visible = false;
  }
};

SidebarScan.prototype.createSearchInput = function() {
  const serchNodes = mxUtils.bind(this, function(evt) {
    const target = evt.target;
    if (target.composing) return;

    this.createScanTree(true, target.value);

    return;
    const nodes = this.zTreeObj.getNodes();
    const inputValue = evt.target.value;
    nodes.forEach(item => {
      item.children = item.children || [];
      item.children.forEach(i => {
        i.isHidden = !i.name.includes(inputValue);
      });

      item.isHidden = !item.name.includes(inputValue) && item.children.every(i => !i.isHidden);
    });
    this.zTreeObj.refresh();
  });

  const tools = document.createElement('div');
  tools.style.display = 'flex';
  tools.style.padding = '4px 16px 0 10px';
  tools.style.alignItems = 'center';

  const elt = document.createElement('input');
  this.searchInput = elt;
  elt.style.width = 'calc(100% - 24px)';
  elt.style.margin = '2px';
  elt.style.border = '2px solid #d3d3d3';
  elt.style.borderRadius = '5px';
  mxEvent.addListener(elt, 'input', serchNodes);
  mxEvent.addListener(elt, 'compositionstart', function(evt) {
    evt.target.composing = true;
  });
  mxEvent.addListener(elt, 'compositionend', function(evt) {
    const target = evt.target;
    if (!target.composing) return;
    target.composing = false;
    target.dispatchEvent(new Event('input'));
  });

  this.searchInput = elt;
  // 阻止冒泡
  elt.addEventListener('keydown', e => {
    if (e.code === 'Enter') {
      this.createScanTree(true, elt.value);
    }
    e.stopPropagation();
  });
  elt.addEventListener('keyup', e => {
    e.stopPropagation();
  });
  tools.appendChild(elt);

  const icons = document.createElement('img');
  icons.src = 'img/tools/clean-icon.svg';
  icons.title = '数据清理';
  icons.style.height = '16px';
  icons.style.marginLeft = '5px';

  icons.addEventListener('click', e => {
    if (drawioBus) {
      drawioBus.$emit('oldDataClearup');
    }
  });

  tools.appendChild(icons);
  this.container.appendChild(tools);
};

// 监听图中新节点的添加
SidebarScan.prototype.processCellAdd = function(sender, evt) {
  // 创建可拖拽节点,调用sidebar中的方法
  // this.zTreeObj.addNodes(null, { name: 'new node', createNode: createNode });
};

SidebarScan.prototype.createNode = function(elt, cells, title) {
  if (!this.editorUi.editor) {
    this.editorUi = myEditor;
  }
  //   const cells = evt.getProperty('cells');
  let cell;
  if (cells[0]) {
    cell = cells[0];
  }

  const geometry = cell.getGeometry();

  const width = geometry.width;
  const height = geometry.height;

  elt.className = elt.className + ' geItem';
  elt.style.display = 'inline-block';
  elt.style.alignItems = 'center';
  elt.style.overflow = 'hidden';
  var border = 2 * this.sidebar.thumbBorder;
  elt.style.width = '100%';
  elt.style.height = 15 + border + 'px';
  elt.style.padding = this.sidebar.thumbPadding + 'px';
  elt.setAttribute('edge', !!cell.edge);

  // Blocks default click action
  mxEvent.addListener(elt, 'click', mxUtils.bind(this, function(evt) {
    this.contextMenu && this.contextMenu.destroy()
    this.contextMenu = null
    mxEvent.consume(evt);
  }));

  this.sidebar.createThumb(cells, 15, 25, elt, title, null, null, width, height);

  var bounds = new mxRectangle(0, 0, width, height);

  if (cells.length > 1 || cells[0].vertex) {
    var ds = this.sidebar.createDragSource(
      elt,
      this.sidebar.createDropHandler(cells, true, null, bounds),
      this.sidebar.createDragPreview(width, height),
      cells,
      bounds
    );
    this.sidebar.addClickHandler(elt, ds, cells);

    // Uses guides for vertices only if enabled in graph
    ds.isGuidesEnabled = mxUtils.bind(this, function() {
      return this.editorUi.editor.graph.graphHandler.guidesEnabled;
    });
  } else if (cells[0] != null) {
    var ds = this.sidebar.createDragSource(
      elt,
      this.sidebar.createDropHandler(cells, false, null, bounds),
      this.sidebar.createDragPreview(width, height),
      cells,
      bounds
    );
    this.sidebar.addClickHandler(elt, ds, cells);
  }

  // Shows a tooltip with the rendered cell
  if (!mxClient.IS_IOS) {
    mxEvent.addGestureListeners(
      elt,
      null,
      mxUtils.bind(this, function(evt) {
        if (mxEvent.isMouseEvent(evt) && !window.isSysml) {
          this.sidebar.showTooltip(elt, cells, bounds.width, bounds.height, title);
        }
      })
    );
  }

  return elt;
};

SidebarScan.prototype.createCellByXml = function(objectXml, id) {
  var objectNode = mxUtils.parseXml(objectXml).documentElement;
  //  '<?xml version="1.0" encoding="UTF-8"?><model tooltip="引用作战活动" type="QUOTE"><quote business="BUSINESS_ACTIVITY" metaId="bd59dc8187754a21bc5b4fe5329b89c3" display="LABEL_ROUND_RECTANGLE" sLabel="" name="作战活动" tooltip="作战活动" label="作战活动" objectId="" quoteId="" name_en="battleactivity"/></model>'
  const displayNode = this.sidebar.getDisplay(objectNode.children[0].getAttribute('display'));

  const width = displayNode.getAttribute('w');
  const height = displayNode.getAttribute('h');
  let style = displayNode.getAttribute('style');
  const display = displayNode.getAttribute('display');

  var cell = new mxCell(objectNode.children[0], new mxGeometry(0, 0, parseInt(width), parseInt(height)), style);
  cell.vertex = true;
  // 标记为直接引用
  if (cell.value && cell.value instanceof Object) {
    cell.value.setAttribute('selectQuote', false);
    cell.value.setAttribute('cellId', id);
  }

  return cell;
};

SidebarScan.prototype.createScanTree = async function(search = false, searchWord = '') {
  const setting = {
    view: {
      selectedMulti: false,
      showIcon: false,
      // 自定义树节点
      addDiyDom: mxUtils.bind(this, function(treeid, treeNode) {
        const aNode = $('#' + treeNode.tId + '_a');

        // aNode.parent()[0].style.display = 'flex'

        // 后档字段由xmlNodeString改成了modelNode，此处是为了兼容其他项目
        const xmlNode = treeNode.modelNode || treeNode.xmlNodeString;
        if (xmlNode) {
          const cell = this.createCellByXml(xmlNode, treeNode.id);
          this.createNode(aNode[0], [cell], treeNode.name);
        }
      })
    },
    callback: {
      onClick: function(event, treeId, treeNode, clickFlag) {
        console.log(event, treeId, treeNode, clickFlag);
        if (treeNode.isFromSearch) {
          getTreeRoot().expandNode(treeNode);
          return;
        }

        var root = getTreeRoot();
        // 切换展开折叠
        if (treeNode.open) {
          root.expandNode(treeNode, false);
          return;
        }

        loadChildren(treeNode).then(data => {
          // 2.展开节点
          data.treeRoot.expandNode(treeNode, true);
        });
      },
      onRightClick: mxUtils.bind(this, this.createContextMenu),
      beforeExpand: function(treeId, treeNode) {
        if (treeNode.count > 0 && (!treeNode.children || !treeNode.children.length)) {
          loadChildren(treeNode).then(data => {
            data.treeRoot.expandNode(treeNode);
          });
        }
        return true;
      }
    }
  };

  function getTreeRoot() {
    return $.fn.zTree.getZTreeObj('scanTree');
  }

  function loadChildren(treeNode) {
    return window.$axios
      .post(window.parent.top.g.ApiUrl2 + '/difine/selectDataDefineObjData', {
        eDefineId: treeNode.id
      })
      .then(res => {
        const data = res.data || [];
        const childrenNode = data.map(item => {
          return {
            name: item.objData.name,
            id: item.objData.id,
            modelNode: item.modelNode,
            pId: treeNode.id,
            metaId: item.objData.meta_id,
            modelId: item.objData.model_id
          };
        });

        function appendTreeNode(pid, childrenNode) {
          if (pid && childrenNode) {
            const treeRoot = getTreeRoot();
            if (treeRoot) {
              const currentNode = treeRoot.getNodeByParam('id', pid);
              if (currentNode) {
                treeRoot.addNodes(currentNode, childrenNode, true);
              }
            }
          }
        }

        const treeRoot = getTreeRoot();
        // 1.添加节点list到父节点下
        treeRoot.removeChildNodes(treeNode);
        if (childrenNode.length) {
          appendTreeNode(treeNode.id, childrenNode);
        }

        return {
          treeRoot: treeRoot,
          childrenNode: childrenNode
        };
      });
  }

  // 递归生成树
  const transTree = data => {
    let result = [];
    let map = {};
    data.forEach(item => {
      map[item.id] = item;
    });
    data.forEach(item => {
      item.drop = true;
      if (item.count > 0) {
        item.children = [];
      }

      let parent = map[item.parentId];
      if (parent) {
        item.parentNodeName = parent.name;
        (parent.children || (parent.children = [])).push(item);
      } else {
        item.parentNodeName = '';
        result.push(item);
      }
    });
    return result;
  };

  let result = [];
  // 获取树形列表
  if (search && searchWord) {
    const res = await window.$axios.post(window.parent.top.g.ApiUrl2 + '/difine/selectDataDefineListForSysml', {
      search: searchWord
    });
    result = res.data || [];
    result.forEach(item => {
      item.isFromSearch = true;
      item.name = item.nodePkgNme;
    });
  } else {
    const res = await window.$axios.get(window.parent.top.g.ApiUrl2 + '/difine/selectDataDefinePkgList');
    result = res.data || [];
    for (let i = 0; i < result.length; i++) {
      const item = result[i];
      item.name = item.nodePkgNme;
      item.id = item.eDefineId;
    }
  }
  this.searchInput.value = searchWord;
  this.treeData = transTree(result);

  this.zTreeObj = $.fn.zTree.init($('#scanTree'), setting, this.treeData);
};

SidebarScan.prototype.removeNodesByIds = function(ids) {
  if (!ids || !ids.length) return;

  ids.forEach(
    mxUtils.bind(this, function(id) {
      var currentNode = this.zTreeObj.getNodeByParam('id', id, null);
      currentNode && this.zTreeObj.removeNode(currentNode, false);
    })
  );
};

SidebarScan.prototype.refreshData = function() {
  var val = this.searchInput && this.searchInput.value;
  this.createScanTree(!!val, val);
};

SidebarScan.prototype.createContextMenu = function(event, _treeId, treeNode) {
  if (!treeNode || !treeNode.modelNode) return;

  const menuMap = [
    {
      name: '编辑',
      show: !!treeNode.modelNode,
      onClick: () => {
        var item = getCell();

        if (item) {
          var cellObj = resolveCell(item.cell);
          cellObj.withCellXml = false;
          attrDialog(item.cell, cellObj, 'edit', function(data) {
            if (window.sidebarStructure) {
              window.sidebarStructure.updateTreeNode();

              window.sidebarScan.refreshData();

              window.sidebarStructure.checkNodeOpening({
                relateId: treeNode.id
              });
            }
          }, { openSource: 'dataDefinition' });
        }
      }
    },
    {
      name: '删除',
      show: () => {
        return !!treeNode.modelNode;
      }, // 视图或者根节点
      onClick: () => {
        const deleteHandle = () => {
          drawioBus.$emit('delStructureNode', {
            hasChildren: treeNode.children && treeNode.children.length,
            fn: mxUtils.bind(this, async function() {
              var item = getCell();
              if (!item) return
              await window.myEditor.actions.get('deleteCellsFromModel').funct([item.cell])
              const n = {
                relateId: treeNode.id
              };
              window.sidebarStructure.checkNodeOpening(n, (cells, graph) => {
                let cells2bRemoved = [];
                Object.keys(cells).forEach(key => {
                  const cell = cells[key];
                  const value = cell.value;
                  if (typeof value === 'object') {
                    if (value.tagName === 'entity' && cells[key].value.getAttribute('objectId') === n.relateId) {
                      cells2bRemoved.push(cell);
                    }
                    if (value.tagName === 'quote' && cells[key].value.getAttribute('quoteId') === n.relateId) {
                      cells2bRemoved.push(cell);
                    }
                  }
                });
                graph.removeCells(cells2bRemoved);
              });
            })
          });
        };

        if (window.myEditor.editor.modified) {
          window.top.$MessageBox
            .confirm('当前设计内容未保存，请先进行保存后再继续', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
            .then(async () => {
              await window.myEditor.saveGraph(1);
              deleteHandle();
            });
        } else {
          deleteHandle();
        }
      }
    }
  ];

  this.contextMenu && this.contextMenu.destroy()
  this.contextMenu = null
  this.contextMenu = new window.DrawioUi.ContextMenu({
    parent: document.body,
    position: { x: event.clientX, y: event.clientY },
    items: menuMap,
  })

  function getCell() {
    var n = mxUtils.parseXml(treeNode.modelNode);
    var xml = '<?xml version="1.0" encoding="UTF-8"?><root>' + n.documentElement.outerHTML + '</root>';
    var fns = myEditor.sidebar.createFns(xml);

    fns[0]();

    return myEditor.sidebar.cellAndStyleMap.find(function(d) {
      var value = d.cell.value;
      var id =
        value.nodeName.toLowerCase() === 'quote' ? value.getAttribute('quoteId') : value.getAttribute('objectId');
      return treeNode.id == id;
    });
  }
};
